"""
Case Type   : 资源池化
Case Name   : 资源池化场景下, 无任何业务压力, 进行probackup操作
Create At   : 2024-04-07
Owner       : songshixuan
Description :
    1、查看集群状态 cm_ctl query -Cv
    2、尝试进行备份
    3、停止集群
    4、开始进行备份
    5、对备一节点进行备份恢复
    6、对集群状态进行查询
Expect      :
    1、集群状态正常，数据库节点状态正常
    2、备份成功
    3、集群停止成功
    4、备份成功
    5、备一节点备份恢复成功
    6、集群状态正常
History     :
    1、2024-04-07 创建
    2、2025-07-12 改造用例为1p1s环境可执行
"""


import os
import unittest
import time

from testcase.utils.ComThread import ComThread
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import macro
from yat.test import Node

Primary_SH = CommonSH('PrimaryDbUser')
Standby1_SH = CommonSH('Standby1DbUser')

@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()

    def test_shared_storage(self):
        Primary_SH.exec_cmd_under_root(f'rm -rf {macro.DB_BACKUP_PATH}')
        text = '-----step1:查看集群状态; expect:集群状态正常-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

        text = '-----step2:尝试进行备份; expect:备份成功，返回success，否则失败-----'
        self.log.info(text)
        status = Primary_SH.exec_pro_backup_init(macro.DB_BACKUP_PATH, get_detail = True)
        self.log.info(status)
        self.assertIn('success', status, '执行失败' + text)
        status = Primary_SH.exec_pro_back_add(macro.DB_BACKUP_PATH, '0', "--enable-dss --instance-id 0 --vgname=\"+data,+log\"", get_detail = True)
        self.log.info(status)
        self.assertIn('inited', status, '执行失败' + text)
        status = Primary_SH.exec_pro_backup_backup(macro.DB_BACKUP_PATH, '0', 'FULL', 'postgres', get_detail = True)
        self.log.info(status)
        self.assertIn('completed', status, '执行失败' + text)

        text = '-----step3:停止集群; expect:停止成功，主节点进入Manually stopped状态-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='stop')
        self.log.info(status)
        self.assertIn(self.constant.cm_stop_success_msg, status,
                      '执行失败' + text)
        
        text = '-----step4:开始执行备份恢复; expect:备份恢复成功,并且关闭dssserver；-----'
        self.log.info(text)
        dataDisk = Primary_SH.exec_cmd_under_user("cat $DSS_HOME/cfg/dss_vg_conf.ini | grep data").split(':')[1]
        self.log.info(dataDisk)
        logDisk = Primary_SH.exec_cmd_under_user("cat $DSS_HOME/cfg/dss_vg_conf.ini | grep log").split(':')[1]
        self.log.info(logDisk)
        dataDiskCmd = f"dd if=/dev/zero of={dataDisk} bs=2048 count=1000 > /dev/null"
        logDiskCmd = f"dd if=/dev/zero of={logDisk} bs=2048 count=1000 > /dev/null"
        Primary_SH.exec_cmd_under_user(dataDiskCmd)
        Primary_SH.exec_cmd_under_user(logDiskCmd)
        status = Primary_SH.exec_cmd_under_user(f"dsscmd cv -g data -v {dataDisk} -D $DSS_HOME")
        self.log.info(status)
        self.assertIn("Succeed", status, '执行失败' + text)
        status = Primary_SH.exec_cmd_under_user(f"dsscmd cv -g log -v {logDisk} -D $DSS_HOME")
        self.log.info(status)
        self.assertIn("Succeed", status, '执行失败' + text)
        Primary_SH.exec_cmd_under_user("rm -rf $PGDATA")
        dss_start = ComThread(Primary_SH.exec_cmd_under_user,
                        args=('dssserver -M -D $DSS_HOME',))
        dss_start.setDaemon(True)
        dss_start.start()
        time.sleep(4)
        dss_start.join(10)
        self.log.info(dss_start.get_result())
        status = Primary_SH.exec_cmd_under_user("ps -ux | grep dssserver")
        self.log.info(status)
        backup_id = Primary_SH.exec_cmd_under_user(f'ls {macro.DB_BACKUP_PATH}/backups/0 | grep -v -- pg_probackup.conf')
        status = Primary_SH.exec_pro_backup_restore(macro.DB_BACKUP_PATH, '0', backup_id, restore_cmd=" -b FULL -d postgres",
                                                get_detail = True)
        self.log.info(status)
        self.assertIn('completed', status, '执行失败' + text)
        dss_start.join(40)
        self.log.info(dss_start.get_result())
        status = Primary_SH.exec_cmd_under_user("dsscmd stopdss")
        self.log.info(status)
        time.sleep(2)
        
        text = '-----step5:备一节点进行备份操作; expect:重新备份成功，并且关闭dssserver，返回success-----'
        self.log.info(text)
        path = Standby1_SH.exec_cmd_under_user("cd $PGDATA;cd ..;pwd")
        dir = Standby1_SH.exec_cmd_under_user("basename $PGDATA")
        Standby1_SH.exec_cmd_under_user(f"cd {path};mv {dir} {dir}_bak")
        status = Standby1_SH.exec_cmd_under_user("dsscmd stopdss")
        self.log.info(status)
        time.sleep(2)

        dss_start = ComThread(Standby1_SH.exec_cmd_under_user,
                        args=('dssserver -M -D $DSS_HOME',))
        dss_start.setDaemon(True)
        dss_start.start()
        time.sleep(4)
        dss_start.join(10)
        self.log.info(dss_start.get_result())
        time.sleep(2)
        initdbStrFind = Standby1_SH.exec_cmd_under_user("cd $GAUSSLOG/om;initdb_str=$(grep gs_init *);echo $initdb_str | grep -o 'gs_initdb.*'")
        self.log.info(initdbStrFind)
        self.assertIn('gs_initdb', initdbStrFind, '执行失败' + text)
        status = Standby1_SH.exec_cmd_under_user(initdbStrFind)
        self.log.info(status)
        self.assertIn('gs_ctl start -D', status, '执行失败' + text)
        Standby1_SH.exec_cmd_under_user(f"cd $PGDATA/..;rm -rf $PGDATA;mv {dir}_bak {dir} ")
        status = Standby1_SH.exec_cmd_under_user("dsscmd stopdss")
        self.log.info(status)
        time.sleep(2)
        
        text = '-----step6:集群重新启动; expect:执行成功-----'
        self.log.info(text)
        startdn = Primary_SH.exec_cm_ctl('start')
        self.log.info(startdn)
        self.assertIn(self.constant.cm_start_success_msg, startdn,
                '拉起dn节点失败')
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)

    def tearDown(self):
        text = '-----step7:恢复环境为初始集群状态; expect:成功-----'
        self.log.info(text)
        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        status = Primary_SH.check_cluster_core_status(status, wait_times=600)
        self.log.info(status)
        recovery = Primary_SH.exec_cm_ctl(mode='switchover', param='-a')
        self.log.info(recovery)
        self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                      '执行失败' + text)

        status = Primary_SH.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')


